﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using OnlineStore.Data;
using OnlineStore.Models;

namespace OnlineStore.Services.Support
{
    public class OrderService : IOrderService
    {
        private readonly OnlineStoreDbContext _context;

        public OrderService(OnlineStoreDbContext context)
        {
            _context = context;
        }

        public List<Order> FindAllOrders()
        {
            return _context.Orders.Include(order => order.User)
                .ToList();
        }

        public List<Order> FindOrderWithState(OrderState state)
        {
            return _context.Orders
                .Include(order => order.ProductInOrders)
                .Where(order => order.State.Equals(state)).ToList();
        }

        public List<ProductComment> FindAllProductComment()
        {
            return _context.ProductComments
                .Include(comment => comment.Product)
                .Include(comment => comment.User)
                .ToList();
        }

        public void SendOrder(Guid uid, int contactId)
        {
            var order = _context.Orders
                .Include(o => o.OrderDetail)
                .FirstOrDefault(o => o.Uid == uid);

            Debug.Assert(order != null, nameof(order) + " != null");
            order.State = OrderState.Shipped;
            order.OrderDetail = new OrderDetail
            {
                ContactInfoId = contactId,
                OrderId = order.Id
            };
            order.DoneTime = DateTime.Now;
            _context.Orders.Update(order);
            _context.SaveChanges();
        }

        public Order FindOrderByUid(Guid uid)
        {
            return _context.Orders
                .Include(order => order.ContactInfo)
                .Include(order => order.ProductInOrders)
                .ThenInclude(pio => pio.Product)
                .Include(order => order.OrderDetail)
                .ThenInclude(detail => detail.ContactInfo)
                .FirstOrDefault(order => order.Uid == uid);
        }

        public async Task SubmitOrder(int userId, int contactId, Dictionary<Product, int> products)
        {
            var inOrders = products.Select(keyValuePair => new ProductInOrder
            { ProductId = keyValuePair.Key.Id, Quantity = keyValuePair.Value }).ToList();
            var newOrder = new Order
            {
                User = await _context.Users.FindAsync(userId),
                ContactInfo = await _context.ContactInfos.FindAsync(contactId),
                CreateTime = DateTime.Now,
                State = OrderState.WaitToDeal,
                Uid = Guid.NewGuid(),
                ProductInOrders = inOrders
            };

            _context.Orders.Add(newOrder);

            foreach (var (key, value) in products)
            {
                var product = _context.Products.Find(key.Id);
                product.SalesVolume += value;
                _context.Products.Update(product);
            }

            await _context.SaveChangesAsync();
        }
    }
}